package jdbc;

import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

import course.RegisteredCourse;

public class RegisteredCourseDao extends DataAccessObject {
	private final String prefix = "RC_";
	private final String table = " RegisteredCourse ";
	private final Class<?> objectClass = RegisteredCourse.class;

	public synchronized ArrayList<RegisteredCourse> selectAllCourses() {

		ArrayList<RegisteredCourse> regCourses = null;
		Connection conn = null;
		CallableStatement callStat = null;
		try {
			conn = getConnection();
			callStat = conn.prepareCall("SELECT * FROM " + table + "ORDER BY "
					+ prefix + "ID");
			callStat.execute();
			ResultSet res = callStat.getResultSet();

			regCourses = new ArrayList<RegisteredCourse>();
			Field[] fields = objectClass.getDeclaredFields();
			AccessibleObject.setAccessible(fields, true);

			while (res.next()) {
				RegisteredCourse rc = new RegisteredCourse();
				for (Field f : fields) {
					setFieldFromResultSet(res, rc, prefix, f);
				}
				regCourses.add(rc);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} finally {
			DataAccessObject.silentClose(conn);
		}
		return regCourses;
	}

	public synchronized void insertRegisteredCourse(RegisteredCourse rc) {
		Connection conn = null;
		try {
			if (rc != null && rc.getCourseId() != null
					&& rc.getStudentId() != null) {
				conn = getConnection();
				PreparedStatement prepStat = null;
				prepStat = conn
						.prepareStatement("INSERT INTO "
								+ table
								+ " ( rc_startDate, rc_finishDate, rc_mark,"
								+ " rc_rating, rc_comment, rc_finished,  "
								+ " rc_courseId, rc_studentId, rc_id) VALUES (?,?,?,?,?,?,?,?,?)");
				prepStat.setLong(1, rc.getStartDate());
				prepStat.setLong(2, rc.getFinishDate());
				prepStat.setString(3, rc.getMark());
				prepStat.setDouble(4, rc.getRating());
				prepStat.setString(5, rc.getComment());
				prepStat.setBoolean(6, rc.isFinished());				
				prepStat.setLong(7, rc.getCourseId());
				prepStat.setLong(8, rc.getStudentId());
				prepStat.setLong(9, rc.getId());
				prepStat.execute();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			DataAccessObject.silentClose(conn);
		}
	}
	
	public RegisteredCourse selectRegisteredCourseById(Long id) {
		if (id == null) {
			System.out.println("NULL id in select " + table + "by id! " + table
					+ "not selected!");
			return null;
		}
		RegisteredCourse rc = null;
		Connection conn = null;
		try {
			conn = getConnection();
			PreparedStatement prepStat = null;
			prepStat = conn.prepareStatement("SELECT * FROM " + table
					+ " WHERE (" + prefix + "ID) = (?);");

			prepStat.setLong(1, id.longValue());

			prepStat.execute();
			ResultSet res = prepStat.getResultSet();
			if (res.first()) {
				Field[] fields = objectClass.getDeclaredFields();
				AccessibleObject.setAccessible(fields, true);
				rc = new RegisteredCourse();
				for (Field f : fields) {
					setFieldFromResultSet(res, rc, prefix, f);
				}
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} finally {
			DataAccessObject.silentClose(conn);
		}
		return rc;
	}
	
	public void updateRegisteredCourse(RegisteredCourse rc) {
		Connection conn = null;
		try {
			conn = getConnection();
			PreparedStatement prepStat = null;
			prepStat = conn
					.prepareStatement("UPDATE "	+ table	+ "set"
							+ " rc_startDate = ?, rc_finishDate = ?, rc_mark = ?,"
							+ " rc_rating = ?, rc_comment = ?, rc_finished = ?,  "
							+ " rc_courseId = ?, rc_studentId = ?"
							+ " where rc_id = ?");

			prepStat.setLong(1, rc.getStartDate());
			prepStat.setLong(2, rc.getFinishDate());
			prepStat.setString(3, rc.getMark());
			prepStat.setDouble(4, rc.getRating());
			prepStat.setString(5, rc.getComment());
			prepStat.setBoolean(6, rc.isFinished());				
			prepStat.setLong(7, rc.getCourseId());
			prepStat.setLong(8, rc.getStudentId());
			prepStat.setLong(9, rc.getId());
			prepStat.execute();
			
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			DataAccessObject.silentClose(conn);
		}
	}
	
	public void deleteRegisteredCourse(RegisteredCourse rc) {
		Connection conn = null;
		try {
			conn = getConnection();
			PreparedStatement prepStat = null;
			if (rc!=null && rc.getId() != null) {
				prepStat = conn.prepareStatement("delete from " + table
						+ "where " + prefix + "ID = ?");
				prepStat.setLong(1, rc.getId());
				prepStat.execute();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			DataAccessObject.silentClose(conn);
		}
	}
	
}
